/*
 * Command.java
 *
 * Created on October 3, 2007, 12:19 AM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package drb;

import java.sql.*;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 *
 * @author Asger
 */
public abstract class Command {
    
    protected static final DateFormat timeFormat = new SimpleDateFormat("HH:mm");
    protected static final DateFormat dateTimeFormat = new SimpleDateFormat("MMM d yyyy, HH:mm");
    protected static final DateFormat dateFormat = new SimpleDateFormat("MMM d yyyy");
    protected static final DateFormat dateNoYearFormat = new SimpleDateFormat("MMM d");
    
    protected Connection connection;
    
    public void setConnection(Connection connection) {
        this.connection = connection;
    }
    
    
    /** Creates a new instance of Command */
    public Command() {
        
    }
    
    public final long ONE_DAY = 24*60*60;
    public final long ONE_YEAR = ONE_DAY * 365; // Approximately one year
    public final long ONE_HOUR = 60*60;
    public final long ONE_MINUTE = 60;
    
    
    public static long getTimeInDays(int days)
    {
        return days * 24 * 60 * 60; // days * 24 hours/day * 60 minutes/hr * 60 seconds/min
    }
    
    public static long getTimeInHours(int hours)
    {
        return hours * 60 * 60;
    }
    
    public static long getTimeInMinutes(int minutes)
    {
        return minutes * 60;
    }
    
    public static long getTimeInterval(int days, int hours, int minutes, int seconds)
    {
        return seconds + 60*(minutes + 60*(hours + 24*days));
    }
    
    public static String formattedTime(long time)
    {
        return timeFormat.format(new java.util.Date(time*1000));
    }
    
    public static String formattedDate(long time)
    {
        return dateFormat.format(new java.util.Date(time*1000));
    }
    
    public static String formattedDateTime(long time)
    {
        return dateTimeFormat.format(new java.util.Date(time*1000));
    }
    
    public static String formattedTimeInterval(long time)
    {
        long seconds = time % 60;
        long minutes = (time / 60) % 60;
        long hours = (time / 60 / 60) % 24;
        long days = (time / 60 / 60 / 24) % 365;
        long years = (time / 60 / 60 / 24 / 365);
        String s = "";
        if (years == 1)
            s += years + " year ";
        else if (years > 1)
            s += years + " years ";
        if (days == 1)
            s += days + " day ";
        else if (days > 1)
            s += days + " days ";
        if (hours == 1)
            s += hours + " hour ";
        else if (hours > 0)
            s += hours + " hours ";
        if (minutes > 0)
            s += minutes + " minutes ";
        if (s.length() == 0)
            return "0 minutes";
        return s;
    }
    
    public static long parseTime(String time) throws ParseException
    {
        return timeFormat.parse(time).getTime() / 1000;
    }
    
    public static  long parseDateTime(String date) throws ParseException
    {
        try {
            return dateTimeFormat.parse(date).getTime() / 1000;
        } catch (ParseException e) {
        }
        return parseDate(date);
    }
    
    public static long parseDate(String date) throws ParseException
    {
        try
        {
            return dateFormat.parse(date).getTime() / 1000;
        } catch (ParseException e)
        {
        }
        return parseDateNoYear(date);
    }
    
    public static long parseDateNoYear(String date) throws ParseException
    {
        long time = dateNoYearFormat.parse(date).getTime() / 1000;
        GregorianCalendar cal = new GregorianCalendar();
        int year = cal.get(Calendar.YEAR);
        cal.setTimeInMillis(time * 1000);
        cal.set(Calendar.YEAR, year);
        return cal.getTimeInMillis() / 1000;
    }
    
    public static long getTodayTime()
    {
        GregorianCalendar cal = new GregorianCalendar();
        cal.setTimeZone(TimeZone.getTimeZone("UTC"));
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        return cal.getTimeInMillis() / 1000;        
    }
    
    public static long getTimeNow()
    {
        return new GregorianCalendar().getTimeInMillis() / 1000;
    }
    
    
    public static String getWeekDayName(long time)
    {
        GregorianCalendar cal = new GregorianCalendar();
        cal.setTimeInMillis(time * 1000);
        int weekday = cal.get(Calendar.DAY_OF_WEEK);
        switch (weekday)
        {
            case Calendar.MONDAY:
                return "Mon";
            case Calendar.TUESDAY:
                return "Tue";
            case Calendar.WEDNESDAY:
                return "Wed";
            case Calendar.THURSDAY:
                return "Thu";
            case Calendar.FRIDAY:
                return "Fri";
            case Calendar.SATURDAY:
                return "Sat";
            case Calendar.SUNDAY:
                return "Sun";
        }
        
        // Suprisingly we do not support 8 days per week.
        assert(false) : "Could not determine weekday.";
        return "";
    }
    
    /**
     * Returns the short name for the current weekday: 'Mon','Tue','Wed','Thu','Fri','Sat', or 'Sun'.
     */
    public static String getWeekDayName()
    {
        return getWeekDayName(getTimeNow());
    }
    
    /**
     * Returns a string where single quotes and backslashes have been escaped by backslashes.
     */
    public static String escapeSQL(String s)
    {
        StringBuffer buffer = new StringBuffer();
        for (int i=0; i<s.length(); i++)
        {
            char c = s.charAt(i);
            switch (c)
            {
                case '\'':
                    buffer.append("\\'");
                    break;
                case '\\':
                    buffer.append("\\\\");
                    break;
                default:
                    buffer.append(c);
            }
        }
        return buffer.toString();
    }
    
    public abstract void execute() throws SQLException;
}
